import {
    createApp,
    h,
    ref,
    Component,
    ComponentInternalInstance
} from 'vue';
import 'element-plus/dist/index.css';
import {SuccessCallback} from "@/components/crud/types";
import CreateDialog from "@/components/crud/form/CreateDialog.vue";
import UpdateDialog from "@/components/crud/form/UpdateDialog.vue";

/**
 * 打开添加对话框
 * @param currentInstance - 当前组件实例
 * @param url - 请求接口地址
 * @param title - 对话框标题
 * @param config - 表单配置
 * @param successCallback
 */
export const openCreateDialog = <T>(currentInstance: ComponentInternalInstance | null, url: string, title: string, config: any[], successCallback: SuccessCallback<T> | null) => {
    // 创建用于挂载对话框的容器
    const container = document.createElement('div');
    document.body.appendChild(container);
    const parentApp = currentInstance?.root.appContext.app;
    // 定义对话框组件引用
    const dialogRef = ref<InstanceType<typeof CreateDialog>>();

    // 创建 Vue 应用实例
    const app = createApp({
        setup() {
            // 渲染 AddDialog 组件
            return () => h(CreateDialog, {
                ref: dialogRef,
                title,
                url,
                config,
                onClose: () => {
                    destroyDialog();
                },
                onSuccess: (data) => {
                    if (typeof successCallback === 'function') {
                        successCallback(data as T);
                    }
                }
            });
        }
    });

    if (parentApp) {

        // 继承全局属性
        Object.assign(app.config.globalProperties, parentApp.config.globalProperties);
        // 继承局部注册组件
        if (currentInstance) {
            // @ts-ignore 绕过 TypeScript 类型检查，获取内部组件定义

            const localComponents = currentInstance.root.appContext.components|| {};
            for (const [name, component] of Object.entries(localComponents)) {
                app.component(name, component as Component);
            }
        }
    }


    // 定义销毁对话框的方法
    const destroyDialog = () => {
        app.unmount();
        document.body.removeChild(container);
    };

    // 挂载应用实例
    app.mount(container);

    // 打开对话框
    if (dialogRef.value) {
        dialogRef.value.open();
    }

    return {
        destroy: destroyDialog
    };
};
/**
 * 打开更新对话框
 * @param currentInstance
 * @param url
 * @param title
 * @param config
 * @param id
 * @param successCallback
 */
export const openUpdateDialog = <T>(currentInstance: ComponentInternalInstance | null, url: string, title: string, config: any[], id: string | number, successCallback: SuccessCallback<T> | null) => {
// 创建用于挂载对话框的容器
    const container = document.createElement('div');
    document.body.appendChild(container);
    const parentApp = currentInstance?.appContext.app;

    // 定义对话框组件引用
    const dialogRef = ref<InstanceType<typeof UpdateDialog>>();

    // 创建 Vue 应用实例
    const app = createApp({
        setup() {
            // 渲染 AddDialog 组件
            return () => h(UpdateDialog, {
                ref: dialogRef,
                title,
                url,
                config,
                onClose: () => {
                    destroyDialog();
                },
                onSuccess: (data) => {
                    if (typeof successCallback === 'function') {
                        successCallback(data as T);
                    }
                }
            });
        }
    });

    if (parentApp) {

        // 继承全局属性
        Object.assign(app.config.globalProperties, parentApp.config.globalProperties);
        // 继承局部注册组件
        if (currentInstance) {
            // @ts-ignore 绕过 TypeScript 类型检查，获取内部组件定义

            const localComponents = currentInstance.root.appContext.components|| {};
            for (const [name, component] of Object.entries(localComponents)) {
                app.component(name, component as Component);
            }
        }
    }

    // 定义销毁对话框的方法
    const destroyDialog = () => {
        app.unmount();
        document.body.removeChild(container);
    };

    // 挂载应用实例
    app.mount(container);

    // 打开对话框
    if (dialogRef.value) {
        dialogRef.value.open(id);
    }

    return {
        destroy: destroyDialog
    };
}
